<?php
namespace Twoir;

/**
 * SiteMap生成器 版本要求 php7.0以上
 * Create 2021.08.20
 * Update 2021.12.14
 * cighsen02 365182575
 */

class SiteMap
{
	protected $no = 1;
	
	protected $step = 1;
	
	protected $table;
	
	protected $temp;
	
	protected $host;
	
	protected $http;
	
	public function __construct(array $option = [], $host = '')
	{
		$host = '' === $host ? $_SERVER['HTTP_HOST'] : str_replace(['http://', 'https://', '/'], '', $host);
		
		$this->host = rtrim($host, '/');
		//协议
		$this->http = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
		
		$this->initialize($option);
	}
	
	//初始化
	protected function initialize(array $option = [])
	{
		$option = \Config::twoir('config');
		
		if (isset($option['sitemap']['model'])) {
			
			$this->table = $option['sitemap']['model'] ?? [];
		}
		
		$this->list();
		
		$this->page();
	}
	
	/**
	 * 拉取数据
	 */
	private function pageData(string $tablename)
	{
		global $dbtbpre, $empire, $class_r, $emod_r;
		
		$sql = $empire->query("select id,classid,title,titleurl, newstime from {$dbtbpre}ecms_" . $tablename . " order by classid");
		
		if($empire->num1($sql) > 0){
			while($r = $empire->fetch($sql)){
				
				$this->temp['page'][] = [
					'url' => $this->http . $this->host . sys_ReturnBqTitleLink($r),
					'name'=> $r['title'],
					'time'=> date('Y-m-d', $r['newstime']) //时间
				];
			}
		}
	}
	
	/**
	 * 列表页
	 */
	public function list()
	{
		global $dbtbpre, $empire, $class_r, $emod_r;
		
		$this->temp['index'][] = [
			'url' => $this->http . $this->host . '/',
			'name'=> '首页'
		];
		
		$sql = $empire->query("select classid, classname, classurl, islast, featherclass, sonclass from {$dbtbpre}enewsclass where showclass=0 order by myorder DESC,classid");
		
		if($empire->num1($sql) > 0){
			while($r = $empire->fetch($sql)){
				
				//输出用户指定的
				if (isset($class_r[$r['classid']]['tbname']) && in_array($class_r[$r['classid']]['tbname'], $this->table)) {
					
					$this->temp['list'][] = [
						'url'	=> $this->http . $this->host . sys_ReturnBqClassname($r, 9),
						'name'	=> $r['classname']
					];
				}
			}
		}
	}
	
	/**
	 * 详情页
	 */
	public function page($time = 0) 
	{
		global $dbtbpre, $empire, $class_r, $emod_r;
		
		if(isset($this->table) && is_array($this->table)) {
			
			foreach($this->table as $tablename) {
				
				$this->pageData($tablename);
			}
		}
	}
	
	private function locMapUrl($loc, $lastmod = null, $changefreq = 'monthly', $priority = 0.6)
	{		
		$str  = '	<url>' . PHP_EOL;
		$str .= '		<loc>' . $loc . '</loc>' . PHP_EOL;
		$str .= '		<lastmod>' . (null === $lastmod ? date('Y-m-d', time()) : $lastmod) . '</lastmod>' . PHP_EOL;
		$str .= '		<changefreq>' . $changefreq . '</changefreq>' . PHP_EOL;
		$str .= '		<priority>' . $priority . '</priority>' . PHP_EOL;
		$str .= '	</url>' . PHP_EOL;
	
		return $str;
	}
	
	private function locMapXml($s, $index)
	{
		if ($index === 1) {
			
			$str  = "<?xml".' version="1.0" encoding="utf-8"?>'."\r\n";
			$str .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'."\r\n" .  $s;
			$str .= "</sitemapindex>"."\r\n";
		} else {
			
			$str  = "<?xml".' version="1.0" encoding="utf-8"?>'."\r\n";
			$str .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'."\r\n" . $s;
			$str .= "</urlset>"."\r\n";
		}
		
		return $str;
	}
	
	public function write($page = 'all', $type = 'xml')
	{		
		$s = '';
		$ins = 'all' === $page ? ['index', 'list', 'page', 'tags'] : [$page];
		$filename = 'sitemap/' . $this->host . '.' . $type;
		//html/txt输出
		if(in_array($type, ['html', 'txt'])) {
			
			foreach(['index' => 0.9, 'list' => 0.8, 'page' => 0.6, 'tags' => 0.7] as $item => $daily) {
				
				if(isset($this->temp[$item]) && in_array($item, $ins)) {
					
					foreach($this->temp[$item] as $no => $value) {
						
						$s .= 'html' === $type ? '<li><a href="' . $value['url'] . '">' . $value['name'] . '</li>' : $value['url'] . PHP_EOL;
					}
				}
			}
			
			if('html' === $type){
				
				$html 	=	'<!DOCTYPE html>';
				$html 	.=	'<html lang="zh">';
				$html 	.=	'<head>';
				$html 	.=	'	<meta charset="UTF-8">';
				$html 	.=	'	<meta name="viewport" content="width=device-width, initial-scale=1.0">';
				$html 	.=	'	<title></title>';
				$html 	.=	'</head>';
				$html 	.=	'<body>';
				$html 	.=	'	<ul>';
				$html 	.=	$s;		
				$html 	.=	'	</ul>';
				$html 	.=	'</body>';
				$html 	.=	'</html>';
					
				$this->writeFileText(ECMS_PATH . DIRECTORY_SEPARATOR . $filename, $html);
			} else {
				
				$this->writeFileText(ECMS_PATH . DIRECTORY_SEPARATOR . $filename, $s);
			}
			
			//echo "\r\n" . '文件已生成: ' . $this->http . $this->host . '/' . $filename . "<br>" . PHP_EOL;
			
		//xml输出
		} elseif('xml' === $type) {
			
			foreach(['index' => 0.9, 'list' => 0.8, 'page' => 0.6, 'tags' => 0.7] as $item => $daily) {
				
				if(isset($this->temp[$item]) && in_array($item, $ins)) {
					
					foreach($this->temp[$item] as $no => $value) {
						
						//转义实体 2021.09.06
						//$value['url'] = str_replace(['&'], ['%26'], $value['url']); //rawurlencode($value['url']);
						$s .= $this->locMapUrl($value['url'], $value['time'] ?? date('Y-m-d', time()), 'daily', $daily);
					}
				}
			}
			
			$s = $this->locMapXml($s, 0);
			$this->writeFileText(ECMS_PATH . DIRECTORY_SEPARATOR . $filename, $s);
			
			//echo "\r\n" . '文件已生成: ' . $this->http . $this->host . '/' . $filename . "<br>" . PHP_EOL;
		
		//打输查看
		} else {

			foreach(['index' => 0.9, 'list' => 0.8, 'page' => 0.6, 'tags' => 0.7] as $item => $daily) {
				
				if(isset($this->temp[$item]) && in_array($item, $ins)) {
					
					foreach($this->temp[$item] as $no => $value) {
						
						echo $value['name'], ': ', $value['url'], ' ', $value['time'], PHP_EOL;
					}
				}
			}
		}
	}
	
	//写入文件
	private function writeFileText($filepath, $string)
	{
		//目录不存在时自动创建目录
		is_dir(dirname($filepath)) or mkdir(dirname($filepath), 0777, true) or die('Failed to create folders...');
		
		$fp = fopen($filepath, "w");
		$r 	= fputs($fp, $string);
		fclose($fp);
		
		return $r;
	}
}